package com.ruoyi.cms.controller.website;

import com.ruoyi.cms.domain.CmsTerritory;
import com.ruoyi.cms.dto.CmsTerritoryDto;
import com.ruoyi.cms.service.ICmsTerritoryService;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 地区层级Controller
 *
 * @author houyong
 * @date 2025-11-09
 */
@Tag(name = "地区层级管理", description = "地区层级管理 for web前端")
@RestController
@RequestMapping("cms/website/territory")
public class CmsSiteTerritoryController extends BaseController {
    @Autowired
    private ICmsTerritoryService cmsTerritoryService;

    /**
     * 查询地区层级列表
     */
    @Operation(summary = "分页查询地区层级列表")
    @GetMapping("/list")
    public TableDataInfo list(CmsTerritory cmsTerritory) {
        startPage();
        List<CmsTerritory> list = cmsTerritoryService.selectCmsTerritoryList(cmsTerritory);
        return getDataTable(list);
    }


    /**
     * 地区层级树形列表
     */
    @Operation(summary = "地区层级树形列表")
    @GetMapping("/trees")
    public AjaxResult exportTree(CmsTerritory cmsTerritory) {
        List<CmsTerritory> list = cmsTerritoryService.selectCmsTerritoryList(cmsTerritory);
        List<CmsTerritoryDto> treeList = buildTreeOptimized(list);
        return success(treeList);
    }

    /**
     * 构建树形结构（Stream优化版）
     *
     * @param list 地区列表
     * @return 树形结构列表
     */
    private List<CmsTerritoryDto> buildTreeOptimized(List<CmsTerritory> list) {
        if (list == null || list.isEmpty()) {
            return new ArrayList<>();
        }

        // 转换并排序
        List<CmsTerritoryDto> sortedDtoList = list.stream()
                .map(this::convertToDto)
                .sorted(Comparator.comparing(CmsTerritoryDto::getTerritorySort,
                        Comparator.nullsLast(Comparator.naturalOrder())))
                .collect(Collectors.toList());

        // 建立映射关系
        Map<String, CmsTerritoryDto> nodeMap = sortedDtoList.stream()
                .collect(Collectors.toMap(CmsTerritoryDto::getId, Function.identity()));

        // 分离根节点和子节点
        Map<Boolean, List<CmsTerritoryDto>> partitioned = sortedDtoList.stream()
                .collect(Collectors.partitioningBy(dto -> StringUtils.isEmpty(dto.getParentId())));

        List<CmsTerritoryDto> rootList = partitioned.get(true);
        List<CmsTerritoryDto> childList = partitioned.get(false);

        // 构建父子关系
        for (CmsTerritoryDto child : childList) {
            CmsTerritoryDto parent = nodeMap.get(child.getParentId());
            if (parent != null) {
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(child);
            } else {
                rootList.add(child);
            }
        }

        return rootList;
    }

    /**
     * 将CmsTerritory转换为CmsTerritoryDto
     *
     * @param territory 原始地区对象
     * @return DTO对象
     */
    private CmsTerritoryDto convertToDto(CmsTerritory territory) {
        CmsTerritoryDto dto = new CmsTerritoryDto();
        BeanUtils.copyProperties(territory, dto);
        return dto;
    }

    /**
     * 获取地区层级详细信息
     */
    @Operation(summary = "获取地区层级详细信息")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        return success(cmsTerritoryService.selectCmsTerritoryById(id));
    }


    @Operation(summary = "根据父级id查询省份下的城市列表")
    @GetMapping(value = "/by/parentId")
    public AjaxResult getInfoByParentId(@RequestParam String id) {
        CmsTerritory cmsTerritory = new CmsTerritory();
        cmsTerritory.setParentId(id);
        return success(cmsTerritoryService.insertCmsTerritory(cmsTerritory));
    }


}
